/* Programação concorrente
 * Projeto Final
 *
 * Ariel Morelli
 * Carlos Pereira Lopes Filho
 * Gustavo Buzogany Eboli
 *
 * Sequêncial
 * Arquivo: smoothS.c
 */

#include <stdio.h>
#include <stdlib.h>

/*seqSmooth
 * Função que retrona a matriz depois de aplicado o filtro smooth de tamanho SIZE
 */
int** seqSmooth(int** mat, int x, int y, int size){
    int i, j, k, l;
    int** result;
    int mean;
    
    //Alocando a matriz
    result = (int **)malloc(y*sizeof(int*));
    for(i = 0; i < y; i++){
        result[i] = (int*)malloc(x*sizeof(int));
    }
    
    //Pegando todos os pixels da imagem
    
    for(i = 0; i < y; i++){
        for(j = 0; j < x; j++){
            //Aplicando o filtro de tamanho size
            mean = 0;
            for(l = -size/2; l < size/2; l++){
                for(k = -size/2; k < size/2; k++){
                    if( (i+l >= 0) && (i+l < y) && (j+k >= 0) && (j+k < x) ){
                        mean = mat[i+l][j+k];
                    }
                    //else mean += 0, essa operação pode ser ignorada.
                }
            }
            mean = (int)(mean/size*size);
            
            result[i][j] = mean;
        }
    }
    return result;
}

int main(int argc, char **argv){
    int x, y, i, j, max;
    int **R, **G, **B;
    int **R2, **G2, **B2;
    FILE *f, *o;
    char line[100], aux;
    
    //Tratamento de parametros
    if( argc != 2 ){
        printf("prog <param1>\n");
        printf("<param1> = imagem .ppm\n");
        return -1;
    }
    
    //Abrir a imagem PPM
    f = fopen(argv[1], "r"); //Arquivo de entrada
    o = fopen("out.ppm", "w+"); //Arquivo de saida
    if ( (f == NULL) || (o == NULL) ){ //Erro ao abrir o arquivo
        printf("Erro ao abrir a imagem.\n");
        return EXIT_FAILURE;
    }
    
    //Primeria linha
    fscanf(f, "%s", line);
    fprintf(o, "%s\n", line);
    
    //Comentários
    fscanf(f, "%c", &aux ); // Recebe o '\n'
    fscanf(f, "%c", &aux ); // Verifica se tem comentários
    
    while( aux == '#'){
        while(aux != '\n'){
            fscanf(f, "%c", &aux ); // Verifica se tem comentários
        }
        fscanf(f, "%c", &aux ); // Verifica se tem comentários
    }
    
    
    fseek(f, -sizeof(char), SEEK_CUR); //vai ter lido o primeiro char que não é # , logo tem que voltar esse char lido.
    
    // Le o valor de x e y
    fscanf(f, "%d %d", &x, &y );
    fprintf(o, "%d %d\n", x, y);
    
    //Alocando matrizes
    //Y - Linhas
    R = (int **)malloc(y*sizeof(int*));
    G = (int **)malloc(y*sizeof(int*));
    B = (int **)malloc(y*sizeof(int*));
    //X - Colunas
    for(i = 0; i < y; i++){
        R[i] = (int*)malloc(x*sizeof(int));
        G[i] = (int*)malloc(x*sizeof(int));
        B[i] = (int*)malloc(x*sizeof(int));
    }
    
    // Valor máximo para normalização
    fscanf(f, "%d", &max );
    fprintf(o, "%d\n", max);
    
    //Lendo valores da matriz
    for(i = 0; i < y; i++){
        for(j = 0; j< x; j++){
            fscanf(f, "%d %d %d", &R[i][j], &G[i][j], &B[i][j]);
        }
    }
    fclose(f);
    
    //Sequencial - aplicar nas 3 matrizes
    R2 = seqSmooth(R, x, y, 5);
    G2 = seqSmooth(G, x, y, 5);
    B2 = seqSmooth(B, x, y, 5);
    
    
    for(i = 0; i < y; i++){
        for(j = 0; j < x; j++){
            fprintf(o, "%d\n%d\n%d\n", R2[i][j], G2[i][j], B2[i][j]);
        }
    }
    fclose(o);
    
    return 0;
}
